package id.web.faisalabdillah.xtimesheet.dao.impl;

import id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao;
import id.web.faisalabdillah.xtimesheet.domain.HolidaysEvent;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.stereotype.Component;

@Component
public class HolidaysDaoImpl implements IHolidaysDao {
	private JpaTemplate jpaTemplate;
	
	@Autowired
	protected void setJpaTempate(EntityManagerFactory entityManagerFactory){
		jpaTemplate = new JpaTemplate(entityManagerFactory);
	}
	
	@Override
	public void insert(HolidaysEvent param) {
		jpaTemplate.persist(param);
	}

	@Override
	public void delete(HolidaysEvent param) {
		jpaTemplate.remove(param);
	}

	@Override
	public void update(HolidaysEvent param) {
		jpaTemplate.merge(param);
	}

	@Override
	public List<HolidaysEvent> findAll() {
		return jpaTemplate.find("select h from HolidaysEvent h");
	}

	@Override
	public List<HolidaysEvent> findByDesc(String param) {
		return jpaTemplate.find("select h from HolidaysEvent h where h.description like ?1", new Object[]{"%"+param+"%"});
	}

	@Override
	public HolidaysEvent findById(long id) {
		return jpaTemplate.find(HolidaysEvent.class, id);
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#findBetweenDate(java.util.Date, java.util.Date)
	 */
	@Override
	public List<HolidaysEvent> findBetweenDate(final Date before, final Date after) {
		return jpaTemplate.execute(new JpaCallback<List<HolidaysEvent>>() {

			@Override
			public List<HolidaysEvent> doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select h from HolidaysEvent h where h.tanggal between ?1 and ?1");
				q.setParameter(1, before);
				q.setParameter(2, after);
				return q.getResultList();
			}
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#sizeAll()
	 */
	@Override
	public int sizeAll() {
		return jpaTemplate.execute(new JpaCallback<Integer>() {

			@Override
			public Integer doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select count(1) from HolidaysEvent");
				return (Integer) q.getSingleResult();
			}
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#sizeBetweenDate(java.util.Date, java.util.Date)
	 */
	@Override
	public int sizeBetweenDate(final Date before, final Date after) {
		return jpaTemplate.execute(new JpaCallback<Integer>() {

			@Override
			public Integer doInJpa(EntityManager em)
					throws PersistenceException {
				Query q=em.createQuery("select count(1) from HolidaysEvent h where h.tanggal between ?1 and ?2");
				q.setParameter(1, before);
				q.setParameter(2, after);
				return (Integer) q.getSingleResult();
			}
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#findAllPaged(int, int)
	 */
	@Override
	public List<HolidaysEvent> findAllPaged(final int first,final int max) {
		return jpaTemplate.execute(new JpaCallback<List<HolidaysEvent>>() {

			@Override
			public List<HolidaysEvent> doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select h from HolidaysEvent h");
				q.setFirstResult(first);
				q.setMaxResults(max);
				return q.getResultList();
			}
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#findByParamsPaged(java.lang.Object, int, int)
	 */
	@Override
	public List<HolidaysEvent> findByDescPaged(final String param,final int first,
			final int max) {
		return jpaTemplate.execute(new JpaCallback<List<HolidaysEvent>>() {

			@Override
			public List<HolidaysEvent> doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select h from HolidaysEvent h where h.description like ?1");
				q.setParameter(1, "%"+param+"%");
				q.setFirstResult(first);
				q.setMaxResults(max);
				return q.getResultList();
			}
			
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#findBetweenDatePaged(java.util.Date, java.util.Date, int, int)
	 */
	@Override
	public List<HolidaysEvent> findBetweenDatePaged(final Date before,final Date after,
			final int first,final int max) {
		return jpaTemplate.execute(new JpaCallback<List<HolidaysEvent>>() {

			@Override
			public List<HolidaysEvent> doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select h from HolidaysEvent h where h.tanggal between ?1 and ?2");
				q.setParameter(1, before);
				q.setParameter(2, after);
				q.setFirstResult(first);
				q.setMaxResults(max);
				return q.getResultList();
			}
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#sizeByParams(java.lang.Object)
	 */
	@Override
	public int sizeByParams(final Object param) {
		return jpaTemplate.execute(new JpaCallback<Integer>() {

			@Override
			public Integer doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select count(1) from HolidaysEvent h where h.description like ?1");
				q.setParameter(1, "%"+param+"%");
				return (Integer) q.getSingleResult();
			}
		});
	}

	/* (non-Javadoc)
	 * @see id.web.faisalabdillah.xtimesheet.dao.IHolidaysDao#findByDate(java.util.Date)
	 */
	@Override
	public HolidaysEvent findByDate(final Date date) {
		return jpaTemplate.execute(new JpaCallback<HolidaysEvent>() {

			@Override
			public HolidaysEvent doInJpa(EntityManager arg0)
					throws PersistenceException {
				Query q=arg0.createQuery("select h from HolidaysEvent h where h.tanggal =?1");
				q.setParameter(1, date);
				return (HolidaysEvent) q.getSingleResult();
			}
		});
	}

}
